package com.example.demo.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONException;
import org.json.XML;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.example.demo.framework.BusinessException;
import com.example.demo.framework.Const;
import com.example.demo.framework.CustomPage;
import com.example.demo.framework.ErrorCode;
import com.example.demo.framework.ResultData;
import com.example.demo.framework.base.BaseController;
import com.example.demo.framework.util.AliPayConfig;
import com.example.demo.framework.util.DoubleUtil;
import com.example.demo.framework.util.JodaUtil;
import com.example.demo.framework.util.SfUtil;
import com.example.demo.model.AfterSale;
import com.example.demo.model.Fund;
import com.example.demo.model.Item;
import com.example.demo.model.Order;
import com.example.demo.model.Sku;
import com.example.demo.model.Storage;
import com.example.demo.model.Trade;
import com.example.demo.model.UserInfo;
import com.example.demo.repository.AfterSaleRepository;
import com.example.demo.repository.FundRepository;
import com.example.demo.repository.ItemRepository;
import com.example.demo.repository.OrderRepository;
import com.example.demo.repository.SkuRepository;
import com.example.demo.repository.StorageRepository;
import com.example.demo.repository.TradeRepository;
import com.example.demo.repository.UserRepository;
import com.example.demo.service.AfterSaleService;
import com.example.demo.service.ItemService;
import com.example.demo.service.TradeService;
import com.example.wanln.util.WanlnApi;
import com.example.wanln.util.WanlnConfig;

@RestController
@RequestMapping("user")
public class UserController extends BaseController {

	@Autowired
	private ItemRepository itemRepository;

	@Autowired
	private SkuRepository skuRepository;

	@Autowired
	private UserRepository userRepository;

	@Autowired
	private FundRepository fundRepository;

	@Autowired
	private OrderRepository orderRepository;

	@Autowired
	private TradeRepository tradeRepository;

	@Autowired
	private AfterSaleRepository afterSaleRepository;

	@Autowired
	private ItemService itemService;

	@Autowired
	private TradeService tradeService;

	@Autowired
	private AfterSaleService afterSaleService;
	
	@Autowired
	private StorageRepository storageRepository;
	
	@Transactional
	@RequestMapping("recharge")
	public Object recharge(Fund fund){
		Map<String, Object> data = new HashMap<>();
		UserInfo user = getUser();
		fund.setFundNo(createOrderID());
		fund.setuID(user.getUserID());
		fund.setCreateTime(JodaUtil.now());
		fund.setBeforeMoney(user.getUserMoney());
		fund.setStatus(0);
		fund.setType(0);
		AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.GATEWAY, AliPayConfig.APP_ID, AliPayConfig.APP_PRIVATE_KEY, "json", AliPayConfig.CHARSET, AliPayConfig.ALIPAY_PUBLIC_KEY, "RSA2"); //获得初始化的AlipayClient
		AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//创建API对应的request类
		request.setNotifyUrl(Const.DOMAIN+AliPayConfig.NOTIFY_URL);
		JSONObject json=new JSONObject();
		json.put("out_trade_no",fund.getFundNo());
		json.put("total_amount", fund.getChangeMoney()+"");
		json.put("subject", "充值金额"+fund.getChangeMoney()+"元");
		json.put("store_id", "NJ_001");
		json.put("timeout_express", "90m");
		request.setBizContent(json.toJSONString());//设置业务参数
		AlipayTradePrecreateResponse response;
		try {
			response = alipayClient.execute(request);
			System.out.print(response.getBody());
			data.put("result", response.getBody());
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		fundRepository.save(fund);
		return new ResultData(data);
	}

	/**
	 * 代理商查询商品
	 * 
	 * @param item
	 * @param pageable
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@RequestMapping("findItem")
	public Object findItem(@RequestParam(value = "pageNo", defaultValue = "0") int pageNo, Item item) {
		Map<String, Object> data = new HashMap<>();
		UserInfo user = getUser();
		item.setStatus(1);
		CustomPage page = itemService.findItem(pageNo(pageNo), PAGESIZE, item,user.getUserLevel());
		if (page.getContent().size() > 0) {
			for (Object obj : page.getContent()) {
				Map<String, Object> m = (Map<String, Object>) obj;
				JSONArray array = JSON.parseArray((String) m.get("skuStr"));
				m.put("skuStr", "");
				m.put("skuJson", array);
				m.put("discount", user.getDiscount());
				m.put("discountPrice", DoubleUtil.mul((Double) m.get("price"), user.getDiscount()));
			}
		}
		data.put("page", page);
		return new ResultData(data);
	}

	/**
	 * 代理商下单
	 * 
	 * @param trade
	 * @return
	 */
	@Transactional
	@RequestMapping("ordering")
	public Object ordering(Trade trade, String sku, String payPassword) {
		Map<String, Object> data = new HashMap<>();
		UserInfo user = getUser();
		if (!user.getPayPassword().equals(payPassword)) {
			return new ResultData(ErrorCode.ERROR_10304, null);
		}
		JSONArray skuArray = JSONArray.parseArray(sku);
		double goodsTotalWeight = 0D;// 商品总重量
		double goodsTotalPrice = 0D;// 商品总价
		long sId=0;
		Order order;
		trade.setTradeID(createOrderID());
		JSONArray ordersArry = new JSONArray();
		for (int i = 0; i < skuArray.size(); i++) {
			JSONObject o = skuArray.getJSONObject(i);
			long skuID = o.getLong("skuID");
			int size = o.getInteger("size");
			Sku s = skuRepository.getBySkuID(skuID);
			if (s == null) {
				return new ResultData(ErrorCode.ERROR_10103, null);
			}
			if (s.getQuantity() - size < 0) {
				return new ResultData(ErrorCode.ERROR_10104, null);
			}
			Item item = itemRepository.getByItemID(s.getItemID());
			if (item == null) {
				return new ResultData(ErrorCode.ERROR_10101, null);
			}
			//判断是否同一一级仓库
			Storage storage= storageRepository.getByID(item.getsID());
			if(i==0){
				if(storage.getsLevel()==2){
					sId=storage.getParentID();
				}else{
					sId=item.getsID();
				}
			}
			if(sId!=item.getsID()){
				if(storage.getsLevel()==2){
					if(sId!=storage.getParentID()){
						return new ResultData(ErrorCode.ERROR_10115, null);
					}
				}else{
					return new ResultData(ErrorCode.ERROR_10115, null);
				}
				
			}
			
			// 修改库存
			JSONArray array = JSON.parseArray(item.getSkuStr());
			JSONArray array2 = new JSONArray();
			for (int j = 0; j < array.size(); j++) {
				Sku sku2 = JSON.parseObject(array.get(j).toString(), new TypeReference<Sku>() {
				});
				if (sku2.getSkuID().equals(skuID)) {
					sku2.setQuantity(sku2.getQuantity() - size);
				}
				array2.add(sku2);
			}
			item.setSkuStr(array2.toString());
			s.setQuantity(s.getQuantity() - size);

			order = new Order();
			order.setSize(size);
			order.setSkuID(s.getSkuID());
			order.setPrice(s.getPrice());
			order.setItemID(s.getItemID());
			order.setItemTitle(item.getTitle());
			order.setStatus(2);
			order.setSkuTitle(s.getAttributes());
			order.setImageUrl(item.getImageURL());
			order.setSnapshot(item.getItemURL());
			order.setOrderID(createOrderID());
			order.setTradeID(trade.getTradeID());
			order.setPayment(DoubleUtil.mul(order.getPrice() * order.getSize(), user.getDiscount()));
			orderRepository.save(order);
			ordersArry.add(order);
			goodsTotalPrice = DoubleUtil.add(goodsTotalPrice, s.getPrice() * size);
			goodsTotalWeight = DoubleUtil.add(goodsTotalWeight, s.getWeight() * size);

		}

		trade.setOtherFee(3.5);// 耗材费3.5
		// 下单支付
		double payPrice = goodsTotalPrice * user.getDiscount() + trade.getOtherFee();
		if (DoubleUtil.sub(user.getUserMoney(), payPrice) < 0) {
			throw new BusinessException(ErrorCode.ERROR_10005);
		}

		trade.setDiscount(user.getDiscount());
		trade.setAfterSale(0);
		trade.setHasRefund(0);
		trade.setUserID(user.getUserID());
		trade.setCreateTime(JodaUtil.now());
		trade.setPayTime(trade.getCreateTime());
		trade.setStatus(2);
		trade.setShopNick(WanlnConfig.SHOP_NICK);
		trade.setModifyTime(trade.getPayTime());
		trade.setBuyer(user.getPhone());
		trade.setTotalWeight(goodsTotalWeight);
		// 金额部分
		trade.setTotalFee(goodsTotalPrice);
		trade.setPayment(payPrice);
		trade.setPostFee(0D);
		trade.setDiscountPrice(DoubleUtil.mul(goodsTotalPrice, user.getDiscount()));
		tradeRepository.save(trade);
		fundRepository.save(Fund.buildPay(trade.getTradeID(), user.getUserID(), trade.getCreateTime(), payPrice,
				user.getUserMoney(), DoubleUtil.sub(user.getUserMoney(), payPrice)));
		user.setUserMoney(DoubleUtil.sub(user.getUserMoney(), payPrice));
		user.setSaleroom(DoubleUtil.add(user.getSaleroom(), payPrice));
		userRepository.save(user);

		// 推送万里牛
		JSONObject tradeObj = (JSONObject) JSON.toJSON(trade);
		tradeObj.put("orders", ordersArry);
		JSONArray trades = new JSONArray();
		trades.add(tradeObj);
		log.info(trades.toJSONString());
		String wlnResponse = WanlnApi.wanlnApiTradesOpen(JSON.toJSONString(trades));
		log.info("万里牛订单推送结果：" + wlnResponse);
		return new ResultData(data);
	}

	/**
	 * 订单列表
	 * 
	 * @param pageNo
	 * @return
	 */
	@RequestMapping("orderList")
	public Object orderList(@RequestParam(value = "pageNo", defaultValue = "0") int pageNo, Trade trade,
			String username) {
		Map<String, Object> data = new HashMap<>();
		trade.setUserID(getUser().getUserID());
		data.put("page", tradeService.findTradeOrder(pageNo(pageNo), PAGESIZE, trade, username));
		return new ResultData(data);
	}

	/**
	 * 订单商品详情
	 * 
	 * @param tradeID
	 * @return
	 */
	@RequestMapping("orderDetail")
	public Object orderDetail(long oID) {
		Map<String, Object> data = new HashMap<>();
		Map<String, Object> map = tradeRepository.getTradeOrder(oID);
		if (map != null) {
			if (map.get("express") != null && "顺丰".equals(map.get("express"))) {
				String xml = SfUtil.sfRouteQueryByOrderNo((String) map.get("logisticsNumber"));
				try {
					org.json.JSONObject xmlJSONObject = XML.toJSONObject(xml);
					JSONObject json = JSON.parseObject(xmlJSONObject.toString());
					data.put("logistics", json);
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
			data.put("orderDetail", map);
		}
		return new ResultData(data);
	}

	/**
	 * 订单签收确认
	 * 
	 * @param tradeID
	 * @return
	 */
	@Transactional
	@RequestMapping("orderAffirm")
	public Object orderAffirm(String tradeID) {
		Map<String, Object> data = new HashMap<>();
		Trade trade = tradeRepository.getByTradeID(tradeID);
		if (trade == null) {
			return new ResultData(ErrorCode.ERROR_10301, null);
		}
		if (trade.getStatus() != 5) {
			return new ResultData(ErrorCode.ERROR_10302, null);
		}
		trade.setStatus(6);
		trade.setModifyTime(JodaUtil.now());

		JSONArray ordersArry = new JSONArray();
		List<Order> list = orderRepository.findByTradeID(trade.getTradeID());
		for (Order o : list) {
			o.setStatus(6);
			ordersArry.add(o);
		}
		// 推送万里牛
		JSONObject tradeObj = (JSONObject) JSON.toJSON(trade);
		tradeObj.put("orders", ordersArry);
		JSONArray trades = new JSONArray();
		trades.add(tradeObj);
		log.info(trades.toJSONString());
		String wlnResponse = WanlnApi.wanlnApiTradesOpen(JSON.toJSONString(trades));
		log.info("万里牛订单确认推送结果：" + wlnResponse);
		return new ResultData(data);
	}

	/**
	 * 售后列表
	 * 
	 * @param pageNo
	 * @return
	 */
	@RequestMapping("afterSaleList")
	public Object afterSaleList(@RequestParam(value = "pageNo", defaultValue = "0") int pageNo, String tradeID,
			String username, Integer status) {
		Map<String, Object> data = new HashMap<>();
		data.put("page", afterSaleService.findAfterSaleTrade(pageNo(pageNo), PAGESIZE, tradeID, getUser().getUserID(),
				username, status));
		return new ResultData(data);
	}

	/**
	 * 售后详情
	 * 
	 * @param tID
	 * @return
	 */
	@RequestMapping("afterSaleDetail")
	public Object afterSaleDetail(long tID) {
		Map<String, Object> data = new HashMap<>();
		data.put("afterSaleDetail", tradeRepository.getTradeOrder(tID));
		return new ResultData(data);
	}

	/**
	 * 提交售后
	 * 
	 * @return
	 */
	@Transactional
	@RequestMapping("submitAfterSale")
	public Object submitAfterSale(AfterSale afterSale) {
		Map<String, Object> data = new HashMap<>();
		Trade trade = tradeRepository.getByTradeID(afterSale.getTradeID());
		if (trade == null) {
			return new ResultData(ErrorCode.ERROR_10301, null);
		}
		if (trade.getStatus() < 3 || trade.getHasRefund() == 1) {
			return new ResultData(ErrorCode.ERROR_10302, null);
		}
		AfterSale as = afterSaleRepository.getBytradeID(afterSale.getTradeID());
		if (as != null) {
			return new ResultData(ErrorCode.ERROR_10352, null);
		}
		trade.setAfterSale(1);
		afterSale.setStatus(0);
		afterSale.setCreatetime(JodaUtil.now());
		afterSaleRepository.save(afterSale);
		return new ResultData(data);
	}

	/**
	 * 创建订单号
	 * 
	 * @return
	 */
	private String createOrderID() {
		return JodaUtil.now(JodaUtil.DATETIME_FORMAT_02) + generateRandomNum6bit();
	}

}
